package socket;

import FCRendering.FCRConstants;
import FCRendering.FCRMaster;
import FCRendering.azer.PlayerAction;
import Function.FCMutilPlayCache;
import Function.FCMutilPlayPropulsionCache;
import Function.FCMutilPlaySender;
import Function.FCMutilPlayTankCache;
import VWorldGameStudio.*;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.reactivex.schedulers.Schedulers;
import socket.protocol.IProtocolServer;
import socket.protocol.ProtocolServerType4;
import socket.util.ByteUtil;
import utils.*;
import utils.entity.BigTankPack;
import utils.entity.MsgPack;
import utils.entity.RandomPack;

import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;

import static FCRendering.FCRMaster.*;

public class FCRSocketClient implements IProtocolServer.OnNeedCallback {

    private static FCRSocketClient socketServer;
    Gson gson = new Gson();

    static {
        socketServer = new FCRSocketClient();
    }

    public static FCRSocketClient getIn() {
        return socketServer;
    }

    private ProtocolServerType4 protocolClient;
    private FCMutilPlaySender senderHelp;
    private Timer timer = null;
    private Object tankLock = new Object();

    private FCRSocketClient() {

    }

    public void initClient() {
        if (protocolClient == null) {
            protocolClient = new ProtocolServerType4(this);
            protocolClient.connect(8, fcv.getConnectIp(), Integer.parseInt(FCRMaster.playerbPort.getText()));
            senderHelp = new FCMutilPlaySender("", protocolClient);
        }
    }

    @Override
    public void onConnectedStatusChanged(String key, boolean connected, Exception e, String msg) {
        if (connected) {
            requestServiceCheckHostId();
            if (timer == null) {
                timer = new Timer();
                timer.schedule(new HeartBoomBoomBoom(), new Date(), 3000);
            }
        } else {
            //清除所有的状态
            ArrayList<String> allHost = new ArrayList<>();
            for (FCPlayerInfo p : FCMutilPlayCache.gamePlayers) {
                if (!allHost.contains(p.getAliasUID())) {
                    allHost.add(p.getAliasUID());
                }
            }
            for (String hostId : allHost) {
                FCMutilPlayCache.aPlayerExitGame(hostId);
            }
        }
    }

    private void sendPlayer() {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendPlayerAndTeam(FCRSocketConstant.C2S_REQUEST_JOIN_SERVER);
    }

    private void requestServiceCheckHostId() {
        if (protocolClient == null) {
            return;
        }

        senderHelp.throughTransmissionSend(FCRSocketConstant.C2S_REQUEST_CHECK_HOSTID, gameSave.HOST_UID.getBytes());
    }

    //表示再同步一次人物属性
    public void reCreatePlayerAgian() {
        sendPlayer();
    }

    /**
     * 人物有移动就发
     */
    public void playerMoving() {
        if (protocolClient == null)
            return;
        if (fcv.isInTeamLink()) {
            //TODO 在别人的队伍中不能操作
            return;
        }
        senderHelp.sendMoving(FCRSocketConstant.C2S_SEND_MOVING);
    }


    public void repoRequestJoin(boolean yesOrNo) {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendRepoRequestJoin(yesOrNo);
    }

    public void playerJoinIn() {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendRequestJoinIn(gameSave.HOST_UID, fcv.getCurTeamMenuClickPlayerHost());
    }

    public void playerJoinOut() {
        if (protocolClient == null) {
            return;
        }
        sendQuitTeam();
    }

    /**
     * 注意了哈，这里不管是队员还是队长都能主动退出队伍 叫对方退出加标志
     */
    private void sendQuitTeam() {
        if (fcv.isInTeamLink()) {
            //就是在别人的队咯，要通知对方把你移除队伍里
            fcv.setInTeamLink(false);
            //TODO 如果有牵引物，就要重整一下
            FCRMaster.player1.resetPropulsionIfNeed();
            //只要给队长发退出就行了
            if (fcv.getTeamLeader() != null) {
                String formToData = gameSave.HOST_UID + "@" + fcv.getTeamLeader();
                byte[] formToDatab = formToData.getBytes();
                byte[] data = new byte[1 + formToDatab.length];
                data[0] = 1;
                System.arraycopy(formToDatab, 0, data, 1, formToDatab.length);
                //TODO 不管怎样都要发一条给人家，
                protocolClient.sendData("", FCRSocketConstant.COMMON_SEND_REQUEST_JOIN_OUT, data);
                fcv.setTeamLeader(null);
            }
        } else {
            ArrayList<String> hostIdNeedSend = new ArrayList<>();
            for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
                if (!link.curPlayerHostUID.equals(gameSave.HOST_UID) && !hostIdNeedSend.contains(link.curPlayerHostUID)) {
                    hostIdNeedSend.add(link.curPlayerHostUID);
                }
            }
            //就是解散整个队伍了，全部人都发
            for (String hostId : hostIdNeedSend) {
                //自己是队长,把非自己的UID的队员全踢了,通知对方把自己的标记设置
                FCMutilPlayCache.removeOtherInTeamNetPlayers(hostId);
                //TODO 移除掉别的玩家的牵引物
                FCRMaster.player1.removeRemotePropulsion(hostId);
                String formToData = gameSave.HOST_UID + "@" + hostId;
                byte[] formToDatab = formToData.getBytes();
                byte[] data = new byte[1 + formToDatab.length];
                data[0] = 0;
                System.arraycopy(formToDatab, 0, data, 1, formToDatab.length);
                //TODO 不管怎样都要发一条给人家，
                protocolClient.sendData("", FCRSocketConstant.COMMON_SEND_REQUEST_JOIN_OUT, data);
            }
            FCRMaster.player1.resetPropulsionIfNeed();
        }
    }

    //申请加入
    public void requestJoinYou() {
        if (protocolClient == null) {
            return;
        }
        if (fcv.isInTeamLink()) {
            //TODO 在别人的队伍中不能操作
            fcv.getMessage().add("你已经在一个队伍里了");
            fcv.showMessage();
            return;
        }
        //TODO 需要对方在同一个地图，不让不能组队
        FCPlayerInfo playerInfo = FCMutilPlayCache.findPlayerByHostId(fcv.getCurTeamMenuClickPlayerHost());
        if (playerInfo != null) {
            if (!playerInfo.getMapname().equals(player1.getMapname())) {
                fcv.getMessage().add("申请组队玩家必须同一地图！");
                fcv.showMessage();
                return;
            }
        } else {
            fcv.getMessage().add("玩家不存在了");
            fcv.showMessage();
            return;
        }
        //TODO 要是自己是队长，不能连续组2个联机玩家
        boolean hasOtherPlayer = false;
        for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
            if (!link.curPlayerHostUID.equals(gameSave.HOST_UID)) {
                hasOtherPlayer = true;
                break;
            }
        }
        if (!hasOtherPlayer) {
            senderHelp.sendRequestJoinYou();
        } else {
            fcv.getMessage().add("不可以连续组更多的玩家了!");
            fcv.showMessage();
        }
    }

    //邀请组队
    public void requestJoinMe() {
        if (protocolClient == null) {
            return;
        }
        if (fcv.isInTeamLink()) {
            //TODO 在别人的队伍中不能操作
            fcv.getMessage().add("你已经在一个队伍里了");
            fcv.showMessage();
            return;
        }
        //TODO 需要对方在同一个地图，不让不能组队
        FCPlayerInfo playerInfo = FCMutilPlayCache.findPlayerByHostId(fcv.getCurTeamMenuClickPlayerHost());
        if (playerInfo != null) {
            if (!playerInfo.getMapname().equals(player1.getMapname())) {
                fcv.getMessage().add("申请组队玩家必须同一地图！");
                fcv.showMessage();
                return;
            }
        } else {
            fcv.getMessage().add("玩家不存在了");
            fcv.showMessage();
            return;
        }

        //TODO 要是自己是队长，不能连续组2个联机玩家
        boolean hasOtherPlayer = false;
        for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
            if (!link.curPlayerHostUID.equals(gameSave.HOST_UID)) {
                hasOtherPlayer = true;
                break;
            }
        }
        if (!hasOtherPlayer) {
            senderHelp.sendRequestJoinMe();
        } else {
            fcv.getMessage().add("不可以连续组更多的玩家了!");
            fcv.showMessage();
        }
    }

    private ArrayList<String> getTeamOtherHostIds() {
        //TODO 这里只有队长才有这些数据
        ArrayList<String> teamHost = new ArrayList<>();
        for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
            if (!link.curPlayerHostUID.equals("npc") && !link.curPlayerHostUID.equals(gameSave.HOST_UID)) {
                if (!teamHost.contains(link.curPlayerHostUID)) {
                    teamHost.add(link.curPlayerHostUID);
                }
            }
        }
        return teamHost;
    }

    //队伍接口
    public void playerJumpEvent(String fcEventName, String destMapName) {
        if (protocolClient == null) {
            return;
        }
        if (fcv.isInTeamLink()) {
            //TODO 在别人的队伍中不能操作
            return;
        }
        //TODO 对方不在你队伍你也不能发
        ArrayList<String> teamhostids = getTeamOtherHostIds();
        if (teamhostids.size() > 0) {
            sendFCJumpEvent(fcEventName, destMapName, teamhostids);
        }
    }

    //队伍接口
    public void syncJumpToBattle() {
        if (protocolClient == null) {
            return;
        }

        //STEP2 优先同步下坦克先
        sendTanksSync();

        ArrayList<String> teamhostids = getTeamOtherHostIds();
        if (teamhostids.size() > 0) {
            sendBattleStart(teamhostids);
        }
    }

    public void syncBattleRandoms(ArrayList<Float> floats) {
        if (protocolClient == null || floats.size() == 0) {
            return;
        }
        ArrayList<String> teamhostids = getTeamOtherHostIds();
        if (teamhostids.size() > 0) {
            RandomPack randomPack = new RandomPack();
            randomPack.floatArrayList = floats;
            randomPack.hostids = teamhostids;
            String data = gson.toJson(randomPack);
            protocolClient.sendData("", FCRSocketConstant.COMMON_BATTLE_RANDOMS, data.getBytes());
        }
    }

    //同步场景变化
    public void syncMultiPlayScreen() {
        if (protocolClient == null) {
            return;
        }
        FCMultiSyncScreenPack teamScreenPack = new FCMultiSyncScreenPack();
        teamScreenPack.doorX = fcrMaster.getOpendoorx();
        teamScreenPack.doorY = fcrMaster.getOpendoory();
        teamScreenPack.isOpenDoor = fcrMaster.isIsplayopendoormusic();
        teamScreenPack.mapName = player1.getMapname();
        teamScreenPack.srcHostId = gameSave.HOST_UID;
        String data = gson.toJson(teamScreenPack);
        protocolClient.sendData("", FCRSocketConstant.COMMON_TEAM_SCREEN_SYNC, data.getBytes());
    }

    //队伍接口
    public void battelReady(FCPlayerBattleWrap s) {
        if (protocolClient == null) {
            return;
        }
        ArrayList<String> teamHost = new ArrayList<>();
        for (FCPlayerBattleWrap wrap : fcv.getBattleWraps()) {
            if (!wrap.getHostUid().equals("npc") && !wrap.getHostUid().equals(gameSave.HOST_UID)) {
                if (!teamHost.contains(wrap.getHostUid())) {
                    teamHost.add(wrap.getHostUid());
                }
            }
        }
        if (teamHost.size() > 0) {
            sendPlayerBattleReady(s, teamHost);
        }
    }

    private void sendPlayerBattleReady(FCPlayerBattleWrap s, ArrayList<String> teamhostids) {
        s.targetHostId = teamhostids;
        String data = gson.toJson(s);
        protocolClient.sendData("", FCRSocketConstant.COMMON_BATTLE_WRAP_SYNC, data.getBytes());
    }

    private void sendFCJumpEvent(String eventName, String map, ArrayList<String> hostIds) {
        String data = map + "@" + eventName + "@" + gameSave.HOST_UID;
        for (String h : hostIds) {
            data = data + "@" + h;
        }
        protocolClient.sendData("", FCRSocketConstant.COMMON_SEND_JUMP_EVENT, data.getBytes());
    }

    //战斗开始进入,只有队长可以发起
    private void sendBattleStart(ArrayList<String> hostIds) {
        FCBattlePack pack = new FCBattlePack();
        for (FCMonster monster : FCRMaster.fcv.getBattleMonster()) {
            pack.monsterId.add(monster.getName());
        }
        pack.targetHostIds.addAll(hostIds);
        pack.battleWraps.addAll(FCRMaster.fcv.getBattleWraps());
        pack.monsterCoors.addAll(FCRMaster.fcv.getBattleMonsterCoor());
        pack.randomVs.addAll(FCRMaster.fcv.getMutilPlayRandomV());
        pack.battleEventId = FCRMaster.fcv.getBattleEvent() != null ? FCRMaster.fcv.getBattleEvent().getName() : null;
        pack.bossRecord = FCRMaster.fcv.getBattleBossRecord();
        pack.buildCoorMaxMonsterW = fcrMaster.fcMonsterBuildCoor.getMaxMonsterW();
        pack.buildCoorLeftPadding = fcrMaster.fcMonsterBuildCoor.getLeftPadding();
        Integer[] coor = fcrMaster.fcMonsterBuildCoor.getLastCoor();
        pack.buildCoorLastCoor = new int[]{coor[0], coor[1], coor[2], coor[3], coor[4], coor[5], coor[6]};
        String data = gson.toJson(pack);
        protocolClient.sendData("", FCRSocketConstant.COMMON_BATTLE_JUMP, data.getBytes());
    }

    public void sendPlayerUpDownTank(FCPlayerInfo p) {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendPlayerUpDownTank(p);
    }

    public void syncPlayerEquip(FCPlayerInfo p) {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendPlayerSyncEquip(p);
    }

    public void syncPlayerState(List<FCPlayerInfo> targetP) {
        if (protocolClient == null) {
            return;
        }
        senderHelp.syncOnePlayerState(targetP);
    }


    public void sendTanksSync() {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendTanksSync();
    }

    public void syncFCPropulsion(FCPropulsion fcPropulsion) {
        if (protocolClient == null) {
            return;
        }
        senderHelp.sendFCPropulsion(fcPropulsion);
    }

    private void syncAllFCPropulsionToClient() {
        if (protocolClient == null) {
            return;
        }

        StringBuilder sp = new StringBuilder();
        for (FCPropulsion fcPropulsion : fcv.getLocalPropulsions()) {
            byte[] s = fcPropulsion.getNetTransportString();
            sp.append(new String(s));
        }
        byte[] sendData = sp.toString().getBytes();
        if (sendData.length > 0) {
            protocolClient.sendData("", FCRSocketConstant.COMMON_SYNC_FCPropulsion, sendData);
        }
    }

    //发送广播消息
    public void sendBrocastPlayerMsg(String msg) {

        if(msg == null){
            player1.setTalkingMsg(null);
            return;
        }
        if(msg.length() == 0){
            player1.setTalkingMsg(null);
            return;
        }
        if("请输入对话".equals(msg)){
            player1.setTalkingMsg(null);
            return;
        }
        if(msg.equals(player1.getTalkingMsg())){
            return;
        }
        if(msg.length() > 20){
            msg = msg.substring(0,20);
        }
        player1.setTalkingMsg(msg);
        if (protocolClient == null) {
            return;
        }
        MsgPack pack = new MsgPack();
        pack.msg = msg;
        pack.playerName = player1.getName();
        pack.hostId = gameSave.HOST_UID;
        String s = gson.toJson(pack);
        byte[] sendData = s.getBytes();
        if (sendData.length > 0) {

            protocolClient.sendData("", FCRSocketConstant.COMMON_PLAYER_TALK_MSG, sendData);
        }
    }

    /**
     * 驾驶操作别的玩家的坦克的区域
     **/
    public void getYouTankItemsToMe(String tankId, String tankHostId) {
        if (protocolClient == null) {
            return;
        }
        String s = tankHostId + "," + tankId + "," + gameSave.HOST_UID;
        protocolClient.sendData("", FCRSocketConstant.COMMON_GIVE_ME_YOUR_TANKITEMS, s.getBytes());
    }

    //上下你的车
    public void upOrDownYouTank(String tankId, String tankHostId, boolean isUp) {
        if (protocolClient == null) {
            return;
        }
        String s = tankHostId + "," + tankId + "," + (isUp ? 1 : 0);
        protocolClient.sendData("", FCRSocketConstant.COMMON_UP_DOWN_YOUR_TANK, s.getBytes());
    }

    //行走后同步
    public void syncYouTankMoving() {
        if (protocolClient == null) {
            return;
        }
        HashMap<String, ArrayList<FCTank>> filters = new HashMap<>();
        //STEP 1判断队伍里是不是有其他玩家的车
        FCPlayerInfo checkPlayer = player1;

        for (int i = -1; i < FCMutilPlayCache.getTeamMembers().size(); i++) {
            if (i == -1) {

            } else {
                FCRPlayerLink link = FCMutilPlayCache.getTeamMembers().get(i);
                checkPlayer = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
            }
            if (checkPlayer != null && checkPlayer.getAliasUID().equals(gameSave.HOST_UID)) {
                if (checkPlayer.getPlayertank1() != null && !checkPlayer.getPlayertank1().equals("null") && !checkPlayer.getPlayertankHostId().equals(gameSave.HOST_UID)) {
                    FCTank fcTank = tankLib.getTankOfID(checkPlayer.getPlayertank1(), checkPlayer.getPlayertankHostId());
                    if (fcTank != null) {
                        ArrayList<FCTank> ls = filters.get(checkPlayer.getPlayertankHostId());
                        if (ls == null) {
                            ls = new ArrayList<>();
                            filters.put(checkPlayer.getPlayertankHostId(), ls);
                        }
                        ls.add(fcTank);
                        FCMutilPlayPropulsionCache.shareIt(fcTank);
                    }
                }
            }
        }
        if (filters.size() > 0) {
            filters.forEach(new BiConsumer<String, ArrayList<FCTank>>() {
                @Override
                public void accept(String s, ArrayList<FCTank> fcTanks) {
                    ArrayList<String> datas = new ArrayList<>(fcTanks.size());
                    for (FCTank fcTank : fcTanks) {
                        datas.add(fcTank.getHostId() + "," + fcTank.getName() + "," + fcTank.getPmapname() + "," + fcTank.getPcoorY()
                                + "," + fcTank.getPcoorY() + "," + fcTank.getPdir() + "," + fcTank.getPactionNum());
                    }
                    String bs = gson.toJson(datas);
                    protocolClient.sendData("", FCRSocketConstant.COMMON_MOVING_YOUR_TANK, bs.getBytes());
                }
            });
        }
    }

    //物品更换了操作
    public void syncOthterPlayerTankStateAndItems() {
        if (protocolClient == null) {
            return;
        }
        ArrayList<FCTank> filters = new ArrayList<>();
        //STEP 1判断队伍里是不是有其他玩家的车
        FCPlayerInfo checkPlayer = player1;
        for (int i = -1; i < FCMutilPlayCache.getTeamMembers().size(); i++) {
            if (i == -1) {
            } else {
                FCRPlayerLink link = FCMutilPlayCache.getTeamMembers().get(i);
                checkPlayer = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
            }
            if (checkPlayer != null && checkPlayer.getAliasUID().equals(gameSave.HOST_UID)) {
                if (checkPlayer.getPlayertank1() != null && !checkPlayer.getPlayertank1().equals("null")) {
                    if (!checkPlayer.getPlayertankHostId().equals(gameSave.HOST_UID)) {
                        FCTank fcTank = tankLib.getTankOfID(checkPlayer.getPlayertank1(), checkPlayer.getPlayertankHostId());
                        if (fcTank != null) {
                            filters.add(fcTank);
                        }
                    }
                }
            }
        }
        for (FCTank fcTank : filters) {
            sendTankStateToTargetHost(fcTank.getName(), fcTank.getHostId(), fcTank.getHostId());
        }
    }

    private void sendTankStateToTargetHost(String tankId, String tankHostId, String targetHost) {
        FCTank fcTank = tankLib.getTankOfID(tankId, tankHostId);
        if (fcTank == null) {
            return;
        }
        BigTankPack bigTankPack = new BigTankPack();
        bigTankPack.tank = fcTank;
        FCItem item = null;
        item = FCRMaster.itemLib.getItemOfID(fcTank.getChassisID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getChassisID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getGunID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getGunID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getGun2ID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getGun2ID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getSEID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getSEID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getEngineID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getEngineID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getRadarID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getRadarID(), item);
        }
        item = FCRMaster.itemLib.getItemOfID(fcTank.getCdeviceID());
        if (item != null) {
            bigTankPack.tankItems.put(fcTank.getCdeviceID(), item);
        }
        for (String k : fcTank.getKnapsack()) {
            if (k != null && k.contains(",")) {
                item = FCRMaster.itemLib.getItemOfID(k);
                if (item != null) {
                    bigTankPack.tankItems.put(k, item);
                }
            }
        }
        String bigData = gson.toJson(bigTankPack);
        //System.out.println(bigData);
        String compressData = FCMixUtil.compress(bigData);
        // System.out.println(compressData);
        String outData = targetHost + "," + compressData;
        protocolClient.sendData("", FCRSocketConstant.COMMON_SYNC_TANK_STATE_ITEMS, outData.getBytes());
    }

    /**
     * 驾驶操作别的玩家的坦克的区域
     **/
    @Override
    public void checkAction(String key, int cmd, long receiveTime, byte... params) {
        System.out.println(receiveTime + "[TIME]Client ==>" + cmd);
        switch (cmd) {
            case FCRSocketConstant.S2C_REPOSNE_CHECK_HOSTID:
                if (params[0] == 1) {
                    //连接后第一个就是
                    sendPlayer();
                    //TODO
                    syncAllFCPropulsionToClient();
                } else {
                    PlayerAction.getInstance().changeHostId = true;
                    String oldHostId = gameSave.HOST_UID;
                    //TODO 改完hostID再申请一次
                    gameSave.HOST_UID = String.valueOf(System.currentTimeMillis()).substring(5);
                    gameSave.getTankSaveIos().forEach(new BiConsumer<String, FCTank>() {
                        @Override
                        public void accept(String s, FCTank tank) {
                            tank.setHostId(gameSave.HOST_UID);
                        }
                    });
                    //删除旧的存档，重新存档
                    File f = new File(FCFileUrl.URL_DATA_SAVE + FCDataSingles.getFileNameDE().filenameEncryption(oldHostId + "-" + player1.getName()) + ".vw");
                    if (f.exists()) {
                        f.delete();
                    }
                    if (FCDataSingles.getWriter().writeSaveData(FCRMaster.player1, FCRMaster.gameSave, FCRMaster.gamedate, FCRMaster.tankLib)) {
                        FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_SUCCESS);
                    } else {
                        FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_FAILURE);
                    }
                    FCRMaster.fcv.getMessage().add("由于和服务器角色存档冲突");
                    FCRMaster.fcv.getMessage().add("-重启游戏重连即可,5秒后关闭");
                    fcv.showMessage();
                    Schedulers.io().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            System.exit(0);
                        }
                    }, 5, TimeUnit.SECONDS);
                }
                break;
            case FCRSocketConstant.S2C_SEND_RES_PLAYER:
                String data = new String(params);
                String uncompress = FCMixUtil.uncompress(data);
                ArrayList<FCPlayerInfo> fcPlayerInfos = gson.fromJson(uncompress, new TypeToken<ArrayList<FCPlayerInfo>>() {
                }.getType());
                for (FCPlayerInfo info : fcPlayerInfos) {
                    if (!info.getAliasUID().equals(gameSave.HOST_UID)) {
                        FCMutilPlayCache.joinGame(info);
                    }
                }
                break;
            case FCRSocketConstant.S2C_SEND_MOVING:
                FCMutilPlayCache.updateMoving(receiveTime, params);
                break;
            case FCRSocketConstant.COMMON_SEND_JOIN:
                byte[] COMMON_SEND_JOINb = new byte[params.length - 1];
                System.arraycopy(params, 1, COMMON_SEND_JOINb, 0, COMMON_SEND_JOINb.length);
                String COMMON_SEND_JOINd = new String(COMMON_SEND_JOINb);
                String[] COMMON_SEND_JOINs = COMMON_SEND_JOINd.split("@");
                FCMutilPlayCache.updateJoinInTeam(params, COMMON_SEND_JOINs);
                //TODO 入队了，主动触发通知一次，当前队伍角色的位置等
                playerMoving();
                break;
            case FCRSocketConstant.COMMON_SEND_REQUEST_JOIN:
                byte[] COMMON_SEND_REQUEST_JOINd = new byte[params.length - 1];
                System.arraycopy(params, 1, COMMON_SEND_REQUEST_JOINd, 0, COMMON_SEND_REQUEST_JOINd.length);
                String[] COMMON_SEND_REQUEST_JOINs = (new String(COMMON_SEND_REQUEST_JOINd)).split("@");
                if (!FCMutilPlayCache.getRequestTeam(params, COMMON_SEND_REQUEST_JOINs)) {
                    //TODO 拒绝对方
                    String fromToData = gameSave.HOST_UID + "@" + COMMON_SEND_REQUEST_JOINs[0];
                    byte[] fromToDatab = fromToData.getBytes();
                    byte[] bytes = new byte[2 + fromToDatab.length];
                    int flag = params[0] & 0xFF;
                    bytes[0] = 0;
                    bytes[1] = (byte) (flag & 0xFF);
                    System.arraycopy(fromToDatab, 0, bytes, 2, fromToDatab.length);
                    protocolClient.sendData("", FCRSocketConstant.COMMON_SEND_REQUEST_JOIN_REPO, bytes);
                }
                break;
            case FCRSocketConstant.COMMON_SEND_REQUEST_JOIN_REPO:
                byte[] COMMON_SEND_REQUEST_JOIN_REPOd = new byte[params.length - 2];
                System.arraycopy(params, 2, COMMON_SEND_REQUEST_JOIN_REPOd, 0, COMMON_SEND_REQUEST_JOIN_REPOd.length);
                String[] COMMON_SEND_REQUEST_JOIN_REPOds = (new String(COMMON_SEND_REQUEST_JOIN_REPOd)).split("@");
                FCMutilPlayCache.getRequestTeamRepo(params, COMMON_SEND_REQUEST_JOIN_REPOds);
                break;
            case FCRSocketConstant.COMMON_SEND_REQUEST_JOIN_OUT:
                byte[] COMMON_SEND_REQUEST_JOIN_OUTd = new byte[params.length - 1];
                System.arraycopy(params, 1, COMMON_SEND_REQUEST_JOIN_OUTd, 0, COMMON_SEND_REQUEST_JOIN_OUTd.length);
                String[] COMMON_SEND_REQUEST_JOIN_OUTs = (new String(COMMON_SEND_REQUEST_JOIN_OUTd)).split("@");
                FCMutilPlayCache.getTeamJoinOut(params, COMMON_SEND_REQUEST_JOIN_OUTs);
                break;
            case FCRSocketConstant.COMMON_SEND_JUMP_EVENT:
                FCMutilPlayCache.parseJumpEvent(params);
                break;
            case FCRSocketConstant.COMMON_SEND_RES_TANKIOS:
                synchronized (tankLock) {
                    String COMMON_SEND_RES_TANKIOSs = new String(params);
                    String uncompressTanks = FCMixUtil.uncompress(COMMON_SEND_RES_TANKIOSs);
                    ArrayList<FCTank> ds = gson.fromJson(uncompressTanks, new TypeToken<ArrayList<FCTank>>() {
                    }.getType());
                    for (FCTank ios : ds) {
                        FCMutilPlayTankCache.updateAndAddTank(ios);
                    }
                }
                break;
            case FCRSocketConstant.COMMON_BATTLE_JUMP:
                //step 1跳转战斗界面
                FCBattlePack pack = gson.fromJson(new String(params), new TypeToken<FCBattlePack>() {
                }.getType());
                FCMutilPlayCache.parseBattleStart(pack);
                break;
            case FCRSocketConstant.COMMON_TEAM_SCREEN_SYNC:
                FCMultiSyncScreenPack fcMultiSyncScreenPack = gson.fromJson(new String(params), FCMultiSyncScreenPack.class);
                FCMutilPlayCache.parseSyncTeamScreen(fcMultiSyncScreenPack);
                break;
            case FCRSocketConstant.COMMON_BATTLE_WRAP_SYNC:
                FCPlayerBattleWrap wrap = gson.fromJson(new String(params), FCPlayerBattleWrap.class);
                FCMutilPlayCache.updateBattleWrap(wrap);
                break;
            case FCRSocketConstant.COMMON_BATTLE_RANDOMS:
                RandomPack randomPack = gson.fromJson(new String(params), RandomPack.class);
                FCMutilPlayCache.updateBattleRandoms(randomPack);
                break;
            case FCRSocketConstant.COMMON_SYNC_EQUIP:
                HashMap<String, String> map = gson.fromJson(new String(params), new TypeToken<HashMap<String, String>>() {
                }.getType());
                FCMutilPlayCache.parseSyncEquip(receiveTime, map);
                break;
            case FCRSocketConstant.COMMON_SYNC_FCPropulsion:
                synchronized (tankLock) {
                    FCMutilPlayPropulsionCache.fromNetShareIt(params, false);
                }
                break;
            case FCRSocketConstant.COMMON_SYNC_UPDOWN_TANK:
                FCMutilPlayCache.parsePlayerUpDownTank(receiveTime, params);
                break;
            case FCRSocketConstant.COMMON_UP_DOWN_YOUR_TANK:
                FCMutilPlayCache.parseRemoteUpDownMyTank(params);
                break;
            case FCRSocketConstant.COMMON_MOVING_YOUR_TANK:
                ArrayList<String> moveData = gson.fromJson(new String(params), new TypeToken<ArrayList<String>>() {
                }.getType());
                FCMutilPlayCache.parseRemoteMoveTank(receiveTime, moveData);
                break;
            case FCRSocketConstant.COMMON_SYNC_TANK_STATE_ITEMS:
                //TODO 同步了过来
                String bigData = new String(params);
                String[] COMMON_SYNC_TANK_STATE_ITEMSsp = bigData.split(",");
                String unCompress = FCMixUtil.uncompress(COMMON_SYNC_TANK_STATE_ITEMSsp[1]);
                BigTankPack bigTankPack = gson.fromJson(unCompress, BigTankPack.class);
                FCMutilPlayCache.paraseRemoteTankItems(bigTankPack);
                break;
            case FCRSocketConstant.COMMON_GIVE_ME_YOUR_TANKITEMS:
                //tankHostId+","+tankId+","+gameSave.HOST_UID;
                String COMMON_GIVE_ME_YOUR_TANKITEMSs = new String(params);
                String[] sp = COMMON_GIVE_ME_YOUR_TANKITEMSs.split(",");
                sendTankStateToTargetHost(sp[1], sp[0], sp[2]);
                break;
            case FCRSocketConstant.COMMON_JOIN_TEAM_FCPropulsion:
                int len = ByteUtil.getInt(new byte[]{params[0], params[1], params[2], params[3]});
                byte[] bytes2 = new byte[params.length - 4 - len];
                System.arraycopy(params, 4 + len, bytes2, 0, bytes2.length);
                FCMutilPlayPropulsionCache.fromNetShareIt(bytes2, true);
                break;
            case FCRSocketConstant.COMMON_S2C_PLAYER_QUIT_GAME:
                FCMutilPlayCache.aPlayerExitGame(new String(params));
                break;
            case FCRSocketConstant.COMMON_CHANGE_PLAYER_LIMIT:
                ArrayList<FCPlayerTransport> list = gson.fromJson(new String(params), new TypeToken<ArrayList<FCPlayerTransport>>() {
                }.getType());
                FCMutilPlayCache.parsePlayerSyncState(receiveTime, list);
                break;
            case FCRSocketConstant.COMMON_PLAYER_TALK_MSG:
                FCMutilPlayCache.parseGetPlayerMsg(gson.fromJson(new String(params),MsgPack.class));
                break;
            default:
                break;
        }
    }


    private class HeartBoomBoomBoom extends TimerTask {

        @Override
        public void run() {
            if (protocolClient != null) {
                protocolClient.sendData("", 0, new byte[]{0});
            }
        }
    }
}
